package com.itheima.health.service.impl;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.health.dao.MenuDao;
import com.itheima.health.entity.PageResult;
import com.itheima.health.entity.QueryPageBean;
import com.itheima.health.pojo.CheckItem;
import com.itheima.health.pojo.Menu;
import com.itheima.health.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Service(interfaceClass = MenuService.class)
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuDao menuDao;

    @Override
    public List<Menu> findMenuList(String username) {
        //1.直接调用Dao查询username对应Menu对象集合
        List<Menu> menuListInDB = menuDao.findMenuList(username);
        if (null != menuListInDB) {
            return orderMenuList(menuListInDB);
        }
        return null;
    }

    @Override
    public List<Menu> findAll() {
        //调用dao查询所有菜单，返回菜单列表
        return menuDao.findAll();
    }

    @Override
    public PageResult<Menu> findPage(QueryPageBean queryPageBean) {
        // pageSize能无限大吗？参数是从前端来的，100W，后台限制大小
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        // 条件查询`
        if (StringUtils.isNotEmpty(queryPageBean.getQueryString())) {
            // 有查询条件，模糊查询
            queryPageBean.setQueryString("%" + queryPageBean.getQueryString() + "%");
        }
        // page extends arrayList
        Page<Menu> page = menuDao.findByCondition(queryPageBean.getQueryString());
        //对Result进行处理
        PageResult<Menu> pageResult = new PageResult<Menu>(page.getTotal(), orderMenuList(page.getResult()));
        return pageResult;
    }

    public List<Menu> orderMenuList(List<Menu> menuListInDB) {
        //2.创建List<Menu>
        List<Menu> menuList = new ArrayList<>();
        //3.遍历集合
        for (Menu menuInDB : menuListInDB) {
            //3.1 如果Path以数字开头，则再次遍历集合，
            if (!menuInDB.getPath().startsWith("/")) {
                String fatherPath = menuInDB.getPath();
                List<Menu> childrenList = menuInDB.getChildren();
                for (Menu childMenu : menuListInDB) {
                    //3.1.1取出以/*-开头的Menu对象添加进children集合
                    String childPath = childMenu.getPath();
                    String usePath = "/" + fatherPath + "-";
                    int beginIndex = usePath.length();
                    if (childPath.startsWith(usePath)) {
                        //3.1.2并设置将后面数字设置为priority
                        childMenu.setPriority(Integer.parseInt(childPath.substring(beginIndex)));
                        childrenList.add(childMenu);
                    }
                    //3.1.3调用排序方法对children集合按照priority进行排序
                    childrenList.sort(new Comparator<Menu>() {
                        @Override
                        public int compare(Menu o1, Menu o2) {
                            //升序
                            return o1.getPriority().compareTo(o2.getPriority());
                        }
                    });
                    //3.1.4将排序后的集合设置为children字段
                    menuInDB.setChildren(childrenList);
                }
                menuInDB.setPriority(Integer.parseInt(menuInDB.getPath()));
                //4.最后将Menu存进集合
                menuList.add(menuInDB);
            }
        }
        //5.对一级菜单进行排序
        menuList.sort(new Comparator<Menu>() {
            @Override
            public int compare(Menu o1, Menu o2) {
                //升序
                return o1.getPriority().compareTo(o2.getPriority());
            }
        });
        //6.返回集合结果
        return menuList;
    }

    /*新增菜单*/
    @Override
    public void add(Menu menu) {
        //获取菜单名判断是否已经有菜单，如果有抛出异常提示用户
        Integer count = menuDao.findByMenuPath(menu.getPath());
        if (count != null && count != 0) {
            throw new RuntimeException();
        }
        //调用dao传入菜单数据，完成添加菜单，返回新增id
        menuDao.add(menu);

        /*//角色菜单关联表：往关联表中和传入角色名和菜单返回id添加一条关联数据
        Integer menuId = menu.getId();
        //调用dao传入菜单id和角色id
        menuDao.addMiddleTable(id,menuId);*/

    }

    /*根据菜单id删除指定菜单*/
    @Override
    public void deleteById(Integer menuId) {
        //调用dao查询t_menu_role表，查询是否有关联的角色信息
        Integer count = menuDao.findById(menuId);
        if (count != 0) {
            throw new RuntimeException();
        }
        menuDao.deleteById(menuId);
    }

    /*修改菜单数据*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Menu menu) {
        //0.判断是否为一级菜单
        if (1 == menu.getLevel()) {
            //0.1是一级菜单
            //1.根据id查询数据库
            Menu originalMenuInDB = menuDao.findMenuById(menu.getId());
            //2判断path是否变更
            if (!originalMenuInDB.getPath().equals(menu.getPath())) {
                //2.1有变更,查询该path是否已存在
                Menu conflictMenuInDB = menuDao.findMenuByPath(menu.getPath());
                if (null != conflictMenuInDB) {
                    //2.1.1已存在，查询出冲突双方一级菜单下属所有二级菜单集合
                    List<Menu> originalChildren = menuDao.findChildrenByPath(originalMenuInDB.getPath());
                    List<Menu> conflictChildren = menuDao.findChildrenByPath(conflictMenuInDB.getPath());
                    //2.1.2遍历集合,下属二级菜单交换path
                    if (originalChildren != null && originalChildren.size() > 0) {
                        for (Menu originalChild : originalChildren) {
                            //处理二级菜单path
                            String childPath = "/" + conflictMenuInDB.getPath() + "-" + originalChild.getPath().substring(3);
                            //更新path
                            menuDao.updatePath(originalChild.getId(), childPath);
                            //更新parent
                            menuDao.updateParent(originalChild.getId(), conflictMenuInDB.getPath());
                        }
                    }
                    if (conflictChildren != null && conflictChildren.size() > 0) {
                        for (Menu conflictChild : conflictChildren) {
                            //处理二级菜单path
                            String childPath = "/" + originalMenuInDB.getPath() + "-" + conflictChild.getPath().substring(3);
                            //更新path
                            menuDao.updatePath(conflictChild.getId(), childPath);
                            //更新parent
                            menuDao.updateParent(conflictChild.getId(), originalMenuInDB.getPath());
                        }
                    }
                    //2.1.3解决一级菜单冲突，交换path
                    menuDao.updatePath(conflictMenuInDB.getId(), originalMenuInDB.getPath());
                }
            }
        } else {
            //0.1是二级菜单
            //1.根据id查询数据库
            Menu originalMenuInDB = menuDao.findMenuById(menu.getId());
            //2.判断该path是否有变更
            if (!originalMenuInDB.getPath().equals(menu.getPath())) {
                //2.1有变更,查询该path是否已存在
                Menu conflictMenuInDB = menuDao.findMenuByPath(menu.getPath());
                if (null != conflictMenuInDB) {
                    //2.1存在,交换path
                    menuDao.updatePath(conflictMenuInDB.getId(), originalMenuInDB.getPath());
                }
            }
        }
        //3.更新菜单
        menuDao.update(menu);
    }

    /*编辑：回显菜单数据*/
    @Override
    public Menu findMenuById(Integer id) {
        //调用dao根据菜单id查询菜单，回显
        return menuDao.findMenuById(id);
    }

    /**
     * 查询所有菜单
     *
     * @return
     */
    @Override
    public List<Menu> findMainAll() {
        List<Menu> menuList = menuDao.findMainAll();
        return menuList;
    }
}